Extract Tile selection algorithms from Tileset into free functions#1342
Extract Tile selection algorithms from Tileset into free functions#1342calebbuffa wants to merge 31 commits into
Tile selection algorithms from Tileset into free functions#1342Conversation
kring
left a comment
There was a problem hiding this comment.
Thanks for the PR @calebbuffa!
I love the way you've broken the tileset selection algorithm into a separate, testable function.
Some of the other changes seem mostly unrelated to this important core, though, and I have some quibbles with them. See below.
| * | ||
| * Tiles at the head are least-recently-used; tiles at the tail are | ||
| * most-recently-used. All methods must be called from the main thread. | ||
| * [main-thread-only] |
There was a problem hiding this comment.
I think this class plays by our thread safety rules just fine. There's no need to further restrict it to "main thread only".
https://cesium.com/learn/cesium-native/ref-doc/thread-safety-rules.html
|
@kring thank you for the feedback! I got a little too carried away. I stripped the changes just to |
Tile selection algorithms from Tileset into free functions
|
I asked Copilot to review this PR, specifically looking for any changes that were inadvertently introduced when I reviewed the code moved from Two issues: 1. Orphaned doc comment in When private:
/**
* @brief When called on an additive-refined tile, queues it for load and adds
* it to the render list.
* ...
* @return false The non-additive-refined tile was ignored.
*/
// ← _loadAndRenderAdditiveRefinedTile declaration was deleted, but this comment wasn't
void _unloadCachedTiles(double timeBudget) noexcept;This happened because the deletion straddled a diff hunk boundary — the Fix: delete the orphaned 2. Unnecessary In auto& childOcclusionProxies =
const_cast<std::vector<const TileOcclusionRendererProxy*>&>(
ctx.childOcclusionProxies);
Fix: remove the |
|
Hi @calebbuffa! We're interested in getting this into the next release, are you able to address Kevin's comments above within the next few days? |
|
@j9liu yes! Sorry got a little sidetracked the last few days. I'll fix the PR by end of week! |
|
Thanks for the updates @calebbuffa! Just for transparency, I think I'll actually defer merging this to after our May 1 release if that's alright. We'll still review this soon, but it would help to have additional time to stress-test the changes, just in case there are any surprises in our runtimes. |
There was a problem hiding this comment.
Pull request overview
This PR refactors the tileset LOD / tile-selection traversal by extracting it from Tileset private methods into a standalone selectTiles() free function, aiming to reduce Tileset surface area and make selection logic more directly testable.
Changes:
- Introduces
selectTiles()andTileSelectionContextas a public entry point for the selection traversal. - Adds
TilesetFrameState::tileStateUpdaterto decouple traversal fromTilesetContentManager. - Refactors tile content eviction tracking behind a new
TileUnloadQueuewrapper and adds new unit tests for the free-function selection path.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Cesium3DTilesSelection/test/TestTilesetSelection.cpp | Adds unit tests that call selectTiles() directly and compare results to Tileset::updateViewGroup. |
| Cesium3DTilesSelection/src/TilesetSelection.cpp | New implementation of the extracted tile-selection / traversal algorithm. |
| Cesium3DTilesSelection/src/Tileset.cpp | Makes updateViewGroup a coordinator that builds frame state/context and calls selectTiles(). |
| Cesium3DTilesSelection/include/Cesium3DTilesSelection/TilesetSelection.h | New public API header defining TileSelectionContext and selectTiles(). |
| Cesium3DTilesSelection/include/Cesium3DTilesSelection/TilesetFrameState.h | Adds tileStateUpdater callback for per-visited-tile state advancement. |
| Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tileset.h | Removes private traversal helpers and includes the new selection header. |
| Cesium3DTilesSelection/src/TilesetContentManager.h | Replaces raw unused-tile linked list member with TileUnloadQueue. |
| Cesium3DTilesSelection/src/TilesetContentManager.cpp | Switches eviction bookkeeping to TileUnloadQueue and adjusts member initialization. |
| Cesium3DTilesSelection/include/Cesium3DTilesSelection/TileUnloadQueue.h | Adds a small wrapper around Tile::UnusedLinkedList for LRU eviction tracking. |
| Cesium3DTilesSelection/include/Cesium3DTilesSelection/Tile.h | Minor doc wording tweak for getParent() comment. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
j9liu
left a comment
There was a problem hiding this comment.
Thank you for the work on this PR @calebbuffa! It might look like there's a lot of comments but I promise they're all minor.
The biggest note is that we lost a lot of helpful internal comments that we should preserve for future knowledge. Otherwise, it's just a matter of style / minor tweaks.
|
@j9liu thank you for the feedback! I mangled one of the files in git diffs accidentally it looks like, I'm reverting the changes and will re-update. |
Description
This PR breaks tile selection algorithms out of private methods in the
Tilesetclass and into free functions. The purpose is to reduce the surface area ofTilesetand make the selection algorithms independently testable.Changes
1) —
tileStateUpdatercallback: decouple traversal from loadingThe traversal helpers (
_visitTileIfNeeded, etc.) previously called_pTilesetContentManager->updateTileContent()directly, creating a compile-time dependency onTilesetContentManagerinside the selection algorithm. Astd::function<void(Tile&)> tileStateUpdaterfield was added toTilesetFrameState.Tileset::updateViewGroupinjects the implementation via a lambda; traversal calls the callback. The traversal has no#includedependency onTilesetContentManager.Files:
TilesetFrameState.h,Tileset.cpp2) —
selectTiles(): pure free function for tile LOD selectionThe entire traversal algorithm (
_visitTileIfNeeded,_visitTile,_renderLeaf,_renderInnerTile,_visitVisibleChildrenNearToFar,_kickDescendantsAndRenderTile,_loadAndRenderAdditiveRefinedTile, frustum/fog cull, occlusion check, SSE computation) was extracted fromTilesetprivate methods into free functions in a new translation unitTilesetSelection.cpp. The public entry point is:Tileset::updateViewGroupis now a thin coordinator: it buildsframeStateand callsselectTiles(). The private traversal method declarations andTraversalDetails/CullResultstructs are gone fromTileset.h.Files:
TilesetSelection.h(new),TilesetSelection.cpp(new),Tileset.h,Tileset.cppIssue number or link
N/A.
Author checklist
CHANGES.mdwith a short summary of my change (for user-facing changes).Testing plan
Regression: All existing tests in
TestTilesetSelectionAlgorithm.cppexercise the full selection pipeline viaTileset::updateViewGroup, which now delegates toselectTiles(). These cover: replace/additive refinement, SSE thresholds, frustum/fog culling, multi-frustum,forbidHoles, LOD transition fade-out,unconditionallyRefine.New isolation test (
TestTilesetSelection.cpp):selectTiles is callable as a free function— constructs a minimalEllipsoidTilesetLoader-backed tileset, callsselectTiles()directly (bypassingTileset::updateViewGroup), and asserts at least one tile is selected with no tiles kicked.selectTiles result matches updateViewGroup result— runs bothupdateViewGroupandselectTiles()on the same warmed-up tileset and asserts tile render count and visit count are identical between the two paths.Build verification:
cmake --build build --target Cesium3DTilesSelectionsucceeds with zero errors.Remaining Tasks
Things that could be done:
TilesetViewGroup::startNewFrame/finishFramestill takeconst Tileset&, which prevents fully async-free unit tests ofselectTiles. Decoupling that is a natural follow-up once this PR lands.